package com.smsc.headend.task.engine.handler.impl.dcuparam;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.smsc.headend.common.enums.BasicParameter;
import com.smsc.headend.common.enums.DeviceType;
import com.smsc.headend.common.enums.NetworkStatus;
import com.smsc.headend.common.enums.PhaseMeterWasion;
import com.smsc.headend.common.enums.errorcode.TaskHandlerErrorCode;
import com.smsc.headend.common.utils.CustomStringUtils;
import com.smsc.headend.common.utils.RedisKeys;
import com.smsc.headend.common.utils.RedisUtils;
import com.smsc.headend.module.asset.dto.FtpDataDto;
import com.smsc.headend.module.asset.entity.ComEntity;
import com.smsc.headend.module.asset.entity.Dcu;
import com.smsc.headend.module.asset.entity.Meter;
import com.smsc.headend.module.asset.entity.PlcMeterStatus;
import com.smsc.headend.module.data.dto.NetWorkTopologyInformationDTO;
import com.smsc.headend.module.data.enums.OperationGroup;
import com.smsc.headend.module.data.enums.OperationName;
import com.smsc.headend.module.ftpntp.entity.NtpServer;
import com.smsc.headend.module.protocol.DeviceData;
import com.smsc.headend.module.protocol.cosem.bo.CosemData;
import com.smsc.headend.module.report.entity.LogPlcNetworkTopology;
import com.smsc.headend.module.task.dto.AtomicTask;
import com.smsc.headend.module.task.dto.Task;
import com.smsc.headend.module.template.dcu.entity.*;
import com.smsc.headend.task.engine.dao.TaskDAO;
import com.smsc.headend.task.engine.exception.UDISTaskHandlerException;
import com.smsc.headend.task.engine.handler.TaskHandler;
import com.smsc.headend.task.engine.service.CosemXmlService;
import com.smsc.headend.task.engine.service.FeignAssetManagementService;
import com.smsc.headend.task.engine.service.asset.AssetService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.smsc.headend.task.engine.utils.StepKeyUtil.getStepKey;


/**
 * @author wxh
 * @date 2020/12/15 20:23
 */
@Slf4j
@Service
public class ReadDcuSimpleDataHandler implements TaskHandler {
    @Autowired
    TaskDAO taskDAO;
    @Autowired
    CosemXmlService cosemXmlService;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    FeignAssetManagementService assetManagementService;
    @Autowired
    AssetService assetService;

    @Override
    public int handle(Task task, AtomicTask atomicTask, DeviceData deviceData, String actionResult) throws UDISTaskHandlerException {
        if (!(deviceData instanceof CosemData)) {
            throw new UDISTaskHandlerException(TaskHandlerErrorCode.DEVICE_DATA_TYPE_NOT_SUPPORT.toString());
        }

        CosemData cosemData = (CosemData) deviceData;
        log.debug("ReadDcuSimpleDataHandler, task{}, deviceData{}", JSONUtil.toJsonStr(task),JSONUtil.toJsonStr(cosemData));
        //Basic参数直接可以解析出来
        switch (OperationName.forId(atomicTask.getOperationId())) {
            case GetDcuClockOverThreshold:
                Object data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.CLOCK_OVER.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuMonthOverThreshold:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.MONTH_OVER.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuBroadcastTimeCheck:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                // 转换后为 HH:mm:ss 返回HH:mm给web
                String time = Convert.toStr(data).substring(0,5);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.BROADCAST.getValue()), time, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuDeviceName:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                String deviceName = HexUtil.decodeHexStr(Convert.toStr(data)).trim();
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.DEVICE_NAME.getValue()), deviceName, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuCommunicationAddr:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                String comAddr = HexUtil.decodeHexStr(Convert.toStr(data)).trim();
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.COMMUNICATION.getValue()), comAddr, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuSignalStrength:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.SIGNAL_STRENGTH.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuLpDensity:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.LOAD_PROFILE.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuGPRSParam:
                List<CosemData> children = cosemData.getChild();
                TemplateParamsDcuGprs paramsDcuGPRS = new TemplateParamsDcuGprs();
                handleDcuGPRSParam(children, paramsDcuGPRS);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.GPRS.getValue()), paramsDcuGPRS, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuEthernetParam:
                children = cosemData.getChild();
                TemplateParamsDcuEthernet paramsDcuEthernet = new TemplateParamsDcuEthernet();
                handDcuEthernetParam(children, paramsDcuEthernet);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.ETHERNET.getValue()), paramsDcuEthernet, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuBasicComParam:
                children = cosemData.getChild();
                TemplateParamsDcuBasic paramsDcuBasic = new TemplateParamsDcuBasic();
                handDcuBasicParam(children, paramsDcuBasic);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.BASIC_COMMUNICATION.getValue()), paramsDcuBasic, Long.valueOf(1 * 60 * 60), true);
                break;
            case FtpParametersGet:
                children = cosemData.getChild();
                FtpDataDto ftpDataDto = new FtpDataDto();
                handDcuFtpParameter(children, ftpDataDto);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.FTP_SETTING.getValue()), ftpDataDto, Long.valueOf(1 * 60 * 60), true);
                break;

            case GetNtpActivated:
                Boolean ntpActived = Convert.toBool(cosemXmlService.getData(cosemData.getType(), cosemData.getValue()));
                log.debug("step getNtpActived success, value {}", ntpActived);
                redisUtils.hset(RedisKeys.getDcuNtpParamActiveKey(task.getTaskNo()), "1", ntpActived ? 1:0, 600);
                break;
            case GetNtpServerAddr:
                String serverAddr = HexUtil.decodeHexStr(Convert.toStr(cosemXmlService.getData(cosemData.getType(), cosemData.getValue()))).trim();
                log.debug("step getNtpServerAddr success, value {}", serverAddr);
                redisUtils.hset(RedisKeys.getDcuNtpParamServerAddrKey(task.getTaskNo()), "1", serverAddr, 600);
                break;
            case GetNtpServerPort:
                Integer ntpPort = Convert.toInt(cosemXmlService.getData(cosemData.getType(), cosemData.getValue()));
                Integer ntpActiveValue = (Integer) redisUtils.hget(RedisKeys.getDcuNtpParamActiveKey(task.getTaskNo()), "1");
                String netServerAddr = (String) redisUtils.hget(RedisKeys.getDcuNtpParamServerAddrKey(task.getTaskNo()), "1");
                NtpServer ntpServer = new NtpServer();
                ntpServer.setActivated(ntpActiveValue);
                ntpServer.setNetAddr(netServerAddr + ":"+ ntpPort);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.NTP_SETTING.getValue()), ntpServer, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetGprsModemApn:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                String apn = HexUtil.decodeHexStr(Convert.toStr(data)).trim();
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.GPRS_MODEM_SETUP.getValue()), apn, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuAutoConnect:
                List<CosemData> childAutoConnect = cosemData.getChild();
                CosemData mainIpPortData = childAutoConnect.get(0);
                String mainIpPort = HexUtil.decodeHexStr(Convert.toStr(cosemXmlService.getData(mainIpPortData.getType(), mainIpPortData.getValue())));
                CosemData backupIpPortData = childAutoConnect.get(1);
                String backupIpPort = HexUtil.decodeHexStr(Convert.toStr(cosemXmlService.getData(backupIpPortData.getType(), backupIpPortData.getValue())));
                TemplateParamsDcuAutoConnect autoConnect = new TemplateParamsDcuAutoConnect();
                autoConnect.setMainServerIp(mainIpPort.split(":")[0]);
                autoConnect.setMainServerPort(Convert.toLong(mainIpPort.split(":")[1]));
                autoConnect.setBackupServerIp(backupIpPort.split(":")[0]);
                autoConnect.setBackupServerPort(Convert.toLong(backupIpPort.split(":")[1]));
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.AUTO_CONNECT.getValue()), autoConnect, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetHeartBeatCycle:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                log.debug("step GetHeartBeatCycle success, value {}", data);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.HEART_BEAT.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetAutoRegisterMode:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                log.debug("step GetAutoRegisterMode success, value {}", data);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.AUTO_REGISTER_MODE.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetRefreshMeterStatus:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                log.debug("step GetRefreshMeterStatus success, value {}", data);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.REFRESH_METER_STATUS.getValue()), data, Long.valueOf(1 * 60 * 60), true);
                break;
            case GetNetworkOnlineMeterList:
                List<String> onlineMeterList = translateNetworkOnlineMeterListCosem(cosemData);
                log.debug("step GetNetworkOnlineMeterList success, value {}", JSONUtil.toJsonStr(onlineMeterList));
                assetManagementService.handlePlcMetersStatus(task.getComId(), onlineMeterList, null);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.NETWORK_ONLINE_METER_LIST.getValue()), JSONUtil.toJsonStr(onlineMeterList), Long.valueOf(1 * 60 * 60), true);
                break;
            case GetNetWorkTopologyInformation:
                List<LogPlcNetworkTopology> netWorkTopologyInformationDTOList = translateNetWorkTopologyInformationCosem(cosemData, task.getComId());
                log.debug("step GetNetWorkTopologyInformation success, value {}", JSONUtil.toJsonStr(netWorkTopologyInformationDTOList));
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.NETWORK_TOPOLOGY_INFORMATION.getValue()), JSONUtil.toJsonStr(netWorkTopologyInformationDTOList), Long.valueOf(1 * 60 * 60), true);
                break;
            case GetDcuPushStatus:
                data = cosemXmlService.getData(cosemData.getType(), cosemData.getValue());
                log.debug("step GetDcuPushStatus success, value {}", data);
                String pushStatus = parsePushStatusValue(data);
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), Convert.toStr(BasicParameter.PUSH_STATUS.getValue()), pushStatus, Long.valueOf(1 * 60 * 60), true);
                break;
            default:
                break;

        }
        return 1;
    }

    private String parsePushStatusValue(Object value) {
        if(null == value) {
            return "";
        }
        String pushStatus = (String) value;
        if(StrUtil.isEmpty(pushStatus)) {
            return "";
        }
        int pushStatusCode = Convert.toInt(pushStatus);
        if(0 == pushStatusCode) {
            return "OFF";
        }
        if(1== pushStatusCode) {
            return "ON";
        }
        return "";
    }

    private TemplateParamsDcuGprs handleDcuGPRSParam(List<CosemData> children, TemplateParamsDcuGprs paramsDcuGPRS) {
        if (children.size() == 7) {
            String mainServerIp = (String) cosemXmlService.getData(children.get(0).getType(), children.get(0).getValue());
            paramsDcuGPRS.setMainServerIp(CustomStringUtils.parseIpAddress(mainServerIp));

            Long mainServerPort = Convert.toLong(cosemXmlService.getData(children.get(1).getType(), children.get(1).getValue()));
            paramsDcuGPRS.setMainServerPort(mainServerPort);

            String backServerIp = (String) cosemXmlService.getData(children.get(2).getType(), children.get(2).getValue());
            paramsDcuGPRS.setBackupServerIp(CustomStringUtils.parseIpAddress(backServerIp));

            Long backServerPort = Convert.toLong(cosemXmlService.getData(children.get(3).getType(), children.get(3).getValue()));
            paramsDcuGPRS.setBackupServerPort(backServerPort);

            String apn = (String) cosemXmlService.getData(children.get(4).getType(), children.get(4).getValue());
            paramsDcuGPRS.setApn(HexUtil.decodeHexStr(apn));

            String userName = (String) cosemXmlService.getData(children.get(5).getType(), children.get(5).getValue());
            paramsDcuGPRS.setUserName(HexUtil.decodeHexStr(userName));


            String userPsw = (String) cosemXmlService.getData(children.get(6).getType(), children.get(6).getValue());
            paramsDcuGPRS.setUserPsw(HexUtil.decodeHexStr(userPsw));
        }
        return paramsDcuGPRS;
    }

    public TemplateParamsDcuEthernet handDcuEthernetParam(List<CosemData> children, TemplateParamsDcuEthernet paramsDcuEthernet) {
        if (children.size() == 3) {
            String localIp = (String) cosemXmlService.getData(children.get(0).getType(), children.get(0).getValue());
            paramsDcuEthernet.setLocalIp(CustomStringUtils.parseIpAddress(localIp));

            String subnetMask = (String) cosemXmlService.getData(children.get(1).getType(), children.get(1).getValue());
            paramsDcuEthernet.setSubnetMask(CustomStringUtils.parseIpAddress(subnetMask));

            String gateway = (String) cosemXmlService.getData(children.get(2).getType(), children.get(2).getValue());
            paramsDcuEthernet.setGateway(CustomStringUtils.parseIpAddress(gateway));
        }
        return paramsDcuEthernet;
    }

    public TemplateParamsDcuBasic handDcuBasicParam(List<CosemData> children, TemplateParamsDcuBasic paramsDcuBasic) {
        if (children.size() == 5) {
            Integer resendTimes = Convert.toInt(cosemXmlService.getData(children.get(0).getType(), children.get(0).getValue()));
            paramsDcuBasic.setResendTimes(resendTimes);

            Integer redialPeriod = Convert.toInt(cosemXmlService.getData(children.get(1).getType(), children.get(1).getValue()));
            paramsDcuBasic.setRedialPeriod(redialPeriod);

            Integer redialTimes = Convert.toInt(cosemXmlService.getData(children.get(2).getType(), children.get(2).getValue()));
            paramsDcuBasic.setRedialTimes(redialTimes);

            Integer onlineMsg = Convert.toInt(cosemXmlService.getData(children.get(3).getType(), children.get(3).getValue()));
            paramsDcuBasic.setOnlineMsg(onlineMsg);

            Integer netStandard = Convert.toInt(cosemXmlService.getData(children.get(4).getType(), children.get(4).getValue()));
            paramsDcuBasic.setNetStandard(netStandard);

            paramsDcuBasic.setNetStandardDes(NetStandard.getNetStandard(netStandard).getDesc());
        }
        return paramsDcuBasic;
    }

    public FtpDataDto handDcuFtpParameter(List<CosemData> children, FtpDataDto ftpDataDto) {
        if (children.size() == 6) {
            Integer protocol = Convert.toInt(cosemXmlService.getData(children.get(0).getType(), children.get(0).getValue()));
            ftpDataDto.setProtocolType(protocol);

            Boolean upLoadEnable = Convert.toBool(cosemXmlService.getData(children.get(1).getType(), children.get(1).getValue()));
            ftpDataDto.setUploadEnable(Convert.toBool(upLoadEnable));

            String uploadUri = (String) cosemXmlService.getData(children.get(2).getType(), children.get(2).getValue());
            ftpDataDto.setUploadUri(HexUtil.decodeHexStr(uploadUri));

            String uploadPw = (String) cosemXmlService.getData(children.get(3).getType(), children.get(3).getValue());
            ftpDataDto.setUploadPw(HexUtil.decodeHexStr(uploadPw));

            String downloadUri = (String) cosemXmlService.getData(children.get(4).getType(), children.get(4).getValue());
            ftpDataDto.setDownLoadUri(HexUtil.decodeHexStr(downloadUri));

            String downLoadPw = (String) cosemXmlService.getData(children.get(5).getType(), children.get(5).getValue());
            ftpDataDto.setDownLoadPw(HexUtil.decodeHexStr(downLoadPw));
        }
        return ftpDataDto;
    }


    @Override
    public int handleFailure(Task task, AtomicTask atomicTask, String message) {
        log.info("error {}, ", message);
        if (atomicTask.getGroupId() == OperationGroup.DcuGetBasicParam.getId().intValue() || atomicTask.getGroupId() == OperationGroup.DcuGetNtpParam.getId().intValue()) {
            String stepOperationName = getStepKey(atomicTask, task);
            if (task.getIsODR()) {
                taskDAO.addTaskData(task.getTaskNo(), atomicTask.getAtomicTaskNo(), stepOperationName, String.format("[%s]", message), 3600l, false);
            }
        }
        return -1;
    }

    /**
     * 转换NetworkOnlineMeter
     *
     * @param cosemData
     * @return
     */
    public List<String> translateNetworkOnlineMeterListCosem(CosemData cosemData) {
        List<String> onlineMeterList = new ArrayList<>();
        if (null == cosemData.getChild()) {
            return onlineMeterList;
        }
        cosemData.getChild().stream().forEach(structData -> {
            for (int index = 0; index < structData.getChild().size(); index++) {
                CosemData data = structData.getChild().get(index);
                if (null != data) {
                    String value = data.getValue();
                    String title = "0000";
                    //威士顿表计特殊处理
                    if (StringUtils.isNotEmpty(value) && value.length() > 4 && title.equals(value.substring(0, 4))) {
                        onlineMeterList.add(value.substring(4));
                    } else {
                        onlineMeterList.add(HexUtil.decodeHexStr(data.getValue()));
                    }
                }
            }
        });
        return onlineMeterList;
    }

    /**
     * 转换NetWorkTopologyInformation
     *
     * @param cosemData
     * @return
     */
    public List<LogPlcNetworkTopology> translateNetWorkTopologyInformationCosem(CosemData cosemData,Long comId) {
        ComEntity terminal = assetService.getComById(comId);
        List<NetWorkTopologyInformationDTO> netWorkTopologyInformationDTOList = new ArrayList<>();
        List<LogPlcNetworkTopology> topologyList = new ArrayList<>();
        Long tvUpdate = SystemClock.now() / 1000;
        String dcuNodeLongAddr = "";
        Dcu dcu =  assetManagementService.getDcuById(terminal.getDeviceId());
        if (CollUtil.isNotEmpty(cosemData.getChild())) {
            // 第一个structure结构中 node_long_address特殊处理为该dcu的资产号
            CosemData rootStrCosemData = cosemData.getChildAt(0).getChildAt(0);
            Object value = cosemXmlService.getData(rootStrCosemData.getType(), rootStrCosemData.getValue());
            dcuNodeLongAddr = value.toString();
        }
        for (int i = 0; i < cosemData.getChild().size(); i++) {
            CosemData structData = cosemData.getChildAt(i);
            NetWorkTopologyInformationDTO netWorkTopologyInformationDTO = new NetWorkTopologyInformationDTO();
            LogPlcNetworkTopology logPlcNetworkTopology = new LogPlcNetworkTopology();
            for (int index = 0; index < structData.getChild().size(); index++) {
                CosemData data = structData.getChild().get(index);
                Object value = cosemXmlService.getData(data.getType(), data.getValue());
                switch (index) {
                    case 0:
                        if (i == 0) {
                            logPlcNetworkTopology.setNodeLongAddr(dcu.getMfgSn());
                            logPlcNetworkTopology.setMeterId(dcu.getDcuId());
                            netWorkTopologyInformationDTO.setNodeLongAddress(dcu.getMfgSn());
                        } else {
                            String meterSerialNo = value.toString();
                            logPlcNetworkTopology.setNodeLongAddr(meterSerialNo);
                            if (StrUtil.isNotEmpty(meterSerialNo)) {
                                Meter meter = assetManagementService.getMeterByMfgSn(meterSerialNo);
                                if (null != meter) {
                                    logPlcNetworkTopology.setMeterId(meter.getMeterId());
                                    logPlcNetworkTopology.setOnlineStatus(getPlcOnlineStatus(meter.getMeterId()));
                                } else {
                                    logPlcNetworkTopology.setDescrb("Meter Not Exist");
                                }
                            }
                            netWorkTopologyInformationDTO.setNodeLongAddress(meterSerialNo);
                        }
                        break;
                    case 1:
                        netWorkTopologyInformationDTO.setNodeShortAddress(Long.parseLong(value.toString()));
                        logPlcNetworkTopology.setNodeShortAddr(value.toString());
                        break;
                    case 2:
                        String parentLongAddr = value.toString();
                        if (i == 0) {
                            logPlcNetworkTopology.setIsRootNode(1);
                            // 第一个根节点是本身 无需设置parentId parentType
                        } else {
                            if (StrUtil.equalsIgnoreCase(parentLongAddr, dcuNodeLongAddr)) {
                                parentLongAddr = dcu.getMfgSn();
                                logPlcNetworkTopology.setParentLongAddr(parentLongAddr);
                                logPlcNetworkTopology.setParentId(dcu.getDcuId());
                                logPlcNetworkTopology.setParentDeviceType(DeviceType.DCU.getId());
                            } else {
                                Meter meter = assetManagementService.getMeterByMfgSn(parentLongAddr);
                                if (null != meter) {
                                    logPlcNetworkTopology.setParentId(meter.getMeterId());
                                    logPlcNetworkTopology.setParentDeviceType(DeviceType.METER.getId());
                                }
                                logPlcNetworkTopology.setParentLongAddr(parentLongAddr);
                            }
                        }
                        netWorkTopologyInformationDTO.setParentNodeLongAddress(parentLongAddr);
                        break;
                    case 3:
                        long signalLength = 0L;
                        if (value != null) {
                            if (NumberUtil.isNumber((String) value)) {
                                signalLength = Long.parseLong((String) value);
                            }
                        }
                        netWorkTopologyInformationDTO.setNodeSignalStrength(signalLength);
                        logPlcNetworkTopology.setSignalStrength(signalLength);
                        break;
                    case 4:
                        String status = NetworkStatus.getById(data.getValue()).getStatus();
                        netWorkTopologyInformationDTO.setNetworkStatus(status);
                        logPlcNetworkTopology.setNetworkStatus(Integer.parseInt(data.getValue()));
                        logPlcNetworkTopology.setNetworkStatusStr(LogPlcNetworkTopology.NetworkStatus.getNetworkStatus(Integer.parseInt(data.getValue())).getText());
                        break;
                    case 5:
                        netWorkTopologyInformationDTO.setGisLongitude(Float.parseFloat(value.toString()));
                        logPlcNetworkTopology.setLongitude(Float.parseFloat(value.toString()));
                        break;
                    case 6:
                        netWorkTopologyInformationDTO.setGisLatitude(Float.parseFloat(value.toString()));
                        logPlcNetworkTopology.setLatitude((Float.parseFloat(value.toString())));
                        break;
                    case 7:
                        String phase = PhaseMeterWasion.getById(data.getValue()).getPhaseName();
                        netWorkTopologyInformationDTO.setPhase(phase);
                        logPlcNetworkTopology.setPhase(Integer.parseInt(data.getValue()));
                        logPlcNetworkTopology.setPhaseStr(LogPlcNetworkTopology.TopologyPhase.getPhaseInfo(Integer.parseInt(data.getValue())).getText());
                        break;
                    default:
                        break;

                }
            }
            logPlcNetworkTopology.setTvUpdate(tvUpdate);
            logPlcNetworkTopology.setSrc(LogPlcNetworkTopology.TopologySrc.Manual.getCode());
            netWorkTopologyInformationDTOList.add(netWorkTopologyInformationDTO);
            topologyList.add(logPlcNetworkTopology);
        };
        if (null != dcu.getDcuId()) {
            //查找当前档案下的meter,将不在当前档案下的meterId置空,用以前端展示为红色
            List<Meter> meters = assetManagementService.getMetersByDcuId(dcu.getDcuId());
            if (CollUtil.isNotEmpty(meters) && CollUtil.isNotEmpty(topologyList)) {
                List<Long> meterIds = meters.stream().map(Meter::getMeterId).collect(Collectors.toList());
                topologyList.forEach(entity -> {
                    if (entity.getParentDeviceType() != null && (!meterIds.contains(entity.getMeterId()))) {
                        entity.setMeterId(null);
                    }
                });
            }
        }
        if (CollUtil.isNotEmpty(topologyList)) {
            assetManagementService.savePlcNetworkRecord(topologyList);
        }
        return topologyList;
    }

    private Integer getPlcOnlineStatus(Long meterId) {
        try {
            PlcMeterStatus plcMeterStatus = assetManagementService.getPlcMeterStatus(meterId);
            if (plcMeterStatus != null) {
                return plcMeterStatus.getStatus();
            }
        } catch (Exception e) {
            log.info("get plcMeterStatus error {}", e.getMessage());
        }
        return null;
    }
}
